<?php
declare (strict_types = 1);

namespace app\user\model;

use app\common\model\Config;
use app\user\model\UserWallet;
use app\myself\WeixinPay;
use app\order\model\PayLog;
use app\volume\model\Volume;
use think\facade\Db;
use think\Model;

/**
 * @mixin \think\Model
 */
class UserVolume extends Model
{
    public $page = '';//分页数据
    public $count = '';//数据总数
    public $error = '';//报错

    /*
     * 获取用户购物券余额总数 //TODO 直接从m3_user_wallet表查volume_balance
     */
    public function getVolumeNum($id){
        return $this->where(['uid'=>$id])->sum('balance');
    }

    /*
     * 获取购物券信息
     */
    public function getVolumeInfo($user){
        try{
            if(empty($user)) exception('找不到该用户!');
            $data = Input('post.');
            $model = new UserWallet();
            $volume = $model->checkVolume($user->id);
            if($user->is_proceeds == 1){
                #已购买购物券 展示列表
                $limit = isset($data['limit'])&&!empty($data['limit']) ? $data['limit'] : 15;//每页显示数据
                $query = ['page' => (isset($data['page']) ? $data['page'] : 1)];//分页参数
                $balances = $this->field('order_sn,balance,add_time,1 as type')->where(['uid'=>$user->id,'status'=>1,'is_delete'=>0])->buildSql();
                $ucash = Db::name('order')->field('order_sn,volume as balance,add_time,2 as type')->where([['uid','=',$user->id],['is_volume','=',1],['status','>',1],['is_delete','=',0]])->unionAll([$balances])->buildSql();
                $item = Db::table($ucash)->alias('union')->order('add_time desc')->paginate($limit, false, array('query'=>$query));
                $list = empty($item) ? array():$item->toArray();
                if(!empty($list['data'])){
                    foreach($list['data'] as $k=>$v){
                        $list['data'][$k]['balance'] = getformat($v['balance']);
                        $list['data'][$k]['add_time'] = date('Y-m-d H:i',$v['add_time']);;
                    }
                }
                $info = [
                    'volume_balance'=>$volume['volume_balance']??0,
                    'list'=>$list,
                ];
            }else{
                #未购买购物券 展示购物券信息
                $mode = new Volume();
                $info = $mode->getOne(['id'=>1]);
                if(!empty($mode->error)) exception($mode->error);
            }
            return $info;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }


    /*
     * 充值购物券
     * @购买购物券必须绑定邀请码和手机号
     */
    public function rechargeVolume($user){
        try{
            if(empty($user)) exception('找不到该用户!');
            $data = Input('post.');
            $time = time();
            $pid = 0;
            /*if(!empty($data['code'])){
                $userPid = (new User())->field('id')->where(['invite_code'=>$data['code'],'is_delete'=>0])->find();
                $pid = !empty($userPid['id']) ? $userPid['id'] : 0;
            }
            if($pid == $user->id) $pid=0;#不能自己分享给自己*/
            if($user->invite_id) $pid = $user->invite_id;#不能自己分享给自己
            $volumeM = new Volume();
            if(!empty($data['id'])) $whereVolume = ['id'=>$data['id'],'status'=>1,'is_delete'=>0];
            else $whereVolume = ['level'=>2,'status'=>1,'is_delete'=>0];
            $ret = $volumeM->field('id,level,initial,price,is_team,is_sale,sale_val,share_grade,start_time,end_time')->where($whereVolume)->find();
            if(empty($ret)) exception('活动已过期!');
            if($ret['start_time']>$time) exception('活动未开启!');
            if($ret['end_time']<$time && $ret['end_time'] != 0) exception('活动已结束!');
            //if($ret['level'] == '5' && $user->level < 5) $pid = 0;
            if($ret['share_grade'] > 1){
                $pUser = (new User())->where(['id'=>$user->invite_id,'is_delete'=>0])->find();
                if((!empty($pUser)&&$pUser['level']<$ret['share_grade']) || empty($pUser)) $pid = 0;
            }

            $order = [
                'uid'=>$user->id,
                'order_sn'=>getNumber('V'),
                'balance'=>$ret['initial'],//购物券金额
                'pay_amount'=>$ret['price'],//实付金额
                'is_team'=>$ret['is_team'],
                'is_sale'=>$ret['is_sale'],
                'volume_id'=>$ret['id'],
                'sale_val'=>$ret['sale_val'],
                'add_time'=>$time,
                'pid'=>$pid,
            ];
            $money = $user->is_fictitious == 1 ? 0.01 : getformat($ret['price']);
            //$money = getformat($ret['price']);
            $wx = new WeixinPay($user->openid,$order['order_sn'],'购物券充值',$money); // $ret['price'] 转为元
            $pay = $wx->pay(); //下单获取返回值
            if(!$pay || !$pay['code'])
                exception(isset($pay['msg']) ? $pay['msg'] : '微信支付发起失败，请稍后重试!');
            if(isset($pay['data']['appId']))
                unset($pay['data']['appId']);
            if($oid = $this->insertGetId($order)){
                $pay_log = (new PayLog())->insertGetId(['uid'=>$user->id,'oid'=>$oid,'orn'=>$order['order_sn'],'request'=>json_encode($pay['data']),'explain'=>'微信支付调起-购物券：'.$ret['price'],'ip'=>0,'add_time'=>$time]);//写入支付记录
                return  $pay['data'];
            }
            exception('支付发起失败，请稍后重试!');
            return false;
        }catch (\Exception $e){
            /*if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else*/ $this->error = $e->getMessage();
            return false;
        }
    }


    /*
     * 充值购物券 回调处理
     */
    public function volumeNotify($dataNotify){
        try{
            $data = isset($dataNotify['data'])?$dataNotify['data']:[];
            if(empty($data)) exception('回调数据为空!');
            $order_sn = isset($dataNotify['data']['out_trade_no'])?$dataNotify['data']['out_trade_no']:'';// 订单号
            // 微信回调写入记录
            $payLogModel = new PayLog();
            if(!empty($order_sn))
                $payLogInfo = $payLogModel->where(['orn'=>$order_sn])->find();
            if(!empty($payLogInfo)){
                $payLogId = $payLogInfo['id'];
                $payLogModel->where(['id'=>$payLogId])->update(['response' => json_encode($dataNotify), 'status' => 1, 'add_time' => time(), 'openid' => ($data['openid']??''), 'ip' => ($dataNotify['ip']??0),'explain'=>'微信支付已回调-购物券']);
            }else{
                $payLogData = [
                    'explain' => '微信支付已回调-购物券',
                    'type' => 1,//支付回调
                    'request' => '', //回调数据
                    'response' => json_encode($dataNotify), //响应数据
                    'add_time' => time(),
                    'status' => 1, //默认没有处理
                    'openid' => ($data['openid']??''), //微信openid
                    'orn' => $order_sn,// 订单号
                    'ip' => ($dataNotify['ip']??0) //ip 地址
                ];
                $payLogId = $payLogModel->insertGetId($payLogData);
            }
            if(empty($order_sn)) exception('不存在该支付记录!');
            //$miaoLog = new MiaoLog();
            $wallet = new UserWallet();
            $userModel = new User();
            $this::startTrans();
            $orderInfo = $this->where(['order_sn'=>$order_sn])->lock(true)->find();
            if(empty($orderInfo)) exception('不存在该支付记录!');
            $orderInfo = $orderInfo->toArray();
            if($orderInfo['status']==1) exception('已完成支付!');
            $walletOperationLog = new WalletOperationLog();
            #开启分销
            $userInfo = $userModel->field('id,level,invite_id')->where(['id'=>$orderInfo['uid'],'is_delete'=>0])->find();
            $userUpdate = ['is_proceeds'=>1];
            if(!empty($userInfo)&&$userInfo['invite_id'] == 0){
                #无邀请码用户绑定成为公司下级客户
                $ret = (new Config())->toData('company');
                if(!empty($ret['account_id'])){
                    $userUpdate['invite_id'] = $orderInfo['pid'] = $userInfo['invite_id'] = $ret['account_id'];
                    $userUpdate['binding_time'] = time();
                    $inviteM = new UserInvite();
                    $inv = $inviteM->where(['uid'=>$userInfo['id']])->update(['upid'=>$ret['account_id'],'pid'=>1,'level'=>$ret['account_id'],'add_time'=>time()]);
                    if($inv) $inviteM->inviteIncPid($userInfo['id'],1,1,['level'=>'','uid'=>$ret['account_id']]);#所有下级pid+1
                }
            }
            $volumeM = new Volume();
            $volume = $volumeM->where(['id'=>$orderInfo['volume_id']])->find();
            #获取上级（推荐人）信息
            $pUser = $userModel->alias('u')->join('user_info i','i.uid=u.id','left')->join('user_level l','l.id=u.level','left')->field('u.id,u.level,u.is_proceeds,i.recommended_num,l.direct_push')->where(['u.id'=>$userInfo['invite_id'],'u.is_delete'=>0])->find();
            if(!empty($pUser) && $pUser['direct_push'] > 0 && $userInfo['level'] == 1){ #判断是否达到直推升级条件
                $userInfoModel = new UserInfo();
                $num = $pUser['recommended_num'] + 1;
                $levelInfo = (new UserLevel())->where(['is_delete'=>0])->field('id')->select();
                $levels[0] = 0;
                if(!empty($levelInfo)){
                    foreach($levelInfo as $k=>$v)
                        $levels[$v['id']] = $v['id'];
                }
                $is_max = max($levels) == $pUser['level'];//判断是否满级
                $is_min = max($levels) < $pUser['level'];//判断是否满级
                if(!$is_max && $num >= $pUser['direct_push']){
                    $i = 1;
                    if(!$is_min){
                        while(!isset($levels[$pUser['level']+$i])){
                            $i++;
                        }
                        $pUserUpdate = $userModel->where(['id'=>$pUser['id']])->update(['level'=>$pUser['level']+$i]);
                    }
                    if(!empty($pUserUpdate)){
                        fileLog(date('Y-m-dHis',time()).'--购物券处理逻辑--用户直推等级提升更新：'.json_encode(['puser'=>$pUser,'level'=>$pUser['level']+$i,'levels'=>$levels]),(date('Y-m-d').'_volume_upLevel.log'));
                        $userInfoModel->where(['uid'=>$pUser['id']])->dec('recommended_num',$pUser['direct_push']-1)->update();
                    }else{
                        fileLog(date('Y-m-dHis',time()).'--购物券处理逻辑--用户直推等级提升更新失败：'.json_encode(['puser'=>$pUser,'level'=>$pUser['level']+$i,'levels'=>$levels]),(date('Y-m-d').'_volume_upLevel.log'));
                        $userInfoModel->where(['uid'=>$pUser['id']])->inc('recommended_num',1)->update();//更新失败数量+1
                    }
                }else{
                    $userInfoModel->where(['uid'=>$pUser['id']])->inc('recommended_num',1)->update();
                }
            }
            #开启分享佣金
            /*if($orderInfo['is_sale'] > 0){
                if(!empty($orderInfo['pid'])){
                    $pUser = $userModel->field('id,level,is_proceeds')->where(['id'=>$orderInfo['pid']])->find();
                    if(!empty($pUser)&&($pUser['is_proceeds'] == 1 || $pUser['level'] > 1)){
                        if($orderInfo['is_sale'] == 1){
                            $sale = (int) ($orderInfo['pay_amount']*($orderInfo['sale_val']/100));
                        }else $sale = $orderInfo['sale_val']*100;
                        $miaoLogData['type'] = 5;
                        $miaoLogData['status'] = 3;
                        $miaoLogData['order_type'] = 2;
                        $miaoLogData['oid'] = $orderInfo['id'];
                        $miaoLogData['uid'] = $pUser['id'];
                        $miaoLogData['reward'] = $sale;
                        $miaoLogData['money'] = $orderInfo['pay_amount'];
                        $miaoLogData['add_time'] = time();
                        $log_id = $miaoLog->insertGetId($miaoLogData);//购物券分销收益miaolog
                        $operationLog = ['uid'=>$pUser['id'],'reward'=>$sale,'status'=>1,'type'=>2,'extend'=>'user_volume','extend_id'=>$orderInfo['id'],'describe'=>'购物券分享收益','add_time'=>time()];
                        $wid = $walletOperationLog->insertGetId($operationLog);
                        $wl = $wallet->where(['uid'=>$pUser['id']])->inc('miao',$sale)->inc('miaos',$sale)->update();
                        $shareModel = new UserShareVolume();
                        //购物券活动记录&分享等级修改
                        if($volume['type'] == 1)
                            $shareid = $shareModel->insertGetId(['uid'=>$userInfo['id'],'puid'=>$orderInfo['pid'],'user_volume_id'=>$orderInfo['id'],'volume_id'=>$volume['id'],'add_time'=>time()]);
                    }
                }
            }*/
            #开启团队累计
//            if($orderInfo['is_team'] == 1){
            #调整团队累计-直接计算团队所有成员收益并写入记录
            $model = new MiaoLog();
            $model->teamSettlement(['uid'=>$orderInfo['uid'],'type'=>2],$orderInfo);
//            }
            #购买购物券活动后提升至对应等级
            if(!empty($volume['level']) && $volume['level']>1 && $volume['level']>$userInfo['level']) $userUpdate['level'] = $volume['level'];
            $userUpdateInfo = $userModel->where(['id'=>$orderInfo['uid']])->update($userUpdate);
            $log = (new UserVolumeLog())->insertGetId([
                'type'=>2,
                'uid'=>$orderInfo['uid'],
                'price'=>$orderInfo['balance'],
                'add_time'=>time(),
                'vid'=>$orderInfo['id'],
            ]);
            $volumeUpdate = $this->where(['id'=>$orderInfo['id']])->update(['status'=>1]);//更新购物券订单状态
            if($walletInfo = $wallet->where(['uid'=>$orderInfo['uid']])->find()){ #增加钱包喵呗记录
                $walletData = [
                    'volume_balance'=>(int)($walletInfo['volume_balance']+$orderInfo['balance']),
                    'volume_total'=>(int)($walletInfo['volume_total']+$orderInfo['balance'])
                ];
                $wallUpdate = $wallet->where(['id'=>$walletInfo['id']])->update($walletData);
                $operationLog = ['uid'=>$orderInfo['uid'],'reward'=>$orderInfo['balance'],'status'=>1,'type'=>5,'extend'=>'user_volume','extend_id'=>$orderInfo['id'],'describe'=>'充值购物券&累计购物券','add_time'=>time()];
                $mywid = $walletOperationLog->insertGetId($operationLog);
                if(!$volumeUpdate || !$userUpdateInfo || !$wallUpdate)
                    fileLog(date('Y-m-dHis',time()).'-购物券处理逻辑---记录异常：'.json_encode(['volumeUpdate'=>$volumeUpdate,'wallUpdate'=>[$wallUpdate,$walletData],'userUpdateInfo'=>[$userUpdateInfo,$userUpdate]]),(date('Y-m-d').'_volume_pay_error.log'));
            }else{ #找不到用户钱包记录，写入日志记录
                fileLog(date('Y-m-dHis',time()).'-购物券处理逻辑---volume回调,找不到用户钱包记录：'.json_encode(['data'=>$dataNotify,'wallet'=>$walletInfo,'where'=>['uid'=>$orderInfo['uid']]]),(date('Y-m-d').'_volume_pay_error.log'));
            }
            $this::commit();
            return true;
        }catch (\Exception $e){
            $this::rollback();
            fileLog(date('Y-m-dHis',time()).'-volume回调：'.json_encode($dataNotify).';err:'.$e->getMessage(),(date('Y-m-d').'_volume_pay_error.log'));//fileLog文件日志 参数1 日志 参数2 文件名
            $this->error = $e->getMessage();
            return false;
        }
    }
}
